''' pxe cfg CRUD '''

import os
import glob

import cfg

class Pxe(object):
    ''' pxe cfg CRUD '''

    def __init__(self, cfg_path=None, pxe_path=None):
        ''' init default values '''
        self._cfg_path = cfg_path if cfg_path else cfg.cfg_path()
        self._pxe_path = pxe_path if pxe_path else cfg.pxe_path()
        self._pxe_prefix = '''ui menu.c32
menu include pxelinux.cfg/ui.cfg
menu title PXE...
'''
    def _getset(self, prop, value=None):
        if value:
            setattr(self, prop, value)
            if prop == '_cfg_path':
                cfg.cfg_path(value)
            elif prop == '_pxe_path':
                cfg.pxe_path(value)
        return getattr(self, prop)

    def cfg_path(self, value=None):
        ''' cfg_path getter/setter '''
        return self._getset('_cfg_path', value)

    def pxe_path(self, value=None):
        ''' pxe_path getter/setter '''
        return self._getset('_pxe_path', value)

    def pxe_prefix(self, value=None):
        ''' pxe_prefix getter/setter '''
        return self._getset('_pxe_prefix', value)

    def list_cfg(self):
        ''' list all cfg files '''
        cfg_files = []
        cfg_path = os.path.normpath(self._cfg_path)
        # cfg_path has no tail slash, so add it to the length
        prefix_len = len(cfg_path) + 1
        for root, dirs, files in os.walk(cfg_path):
            cfg_files.extend([
                os.path.normpath(os.path.join(root, i))[prefix_len:].replace(
                    os.sep, '/') for i in files
                if i.endswith('.cfg') and i != 'menu.cfg'
            ])
        return sorted(cfg_files)

    def get_cfg(self, cfg_name):
        ''' get cfg file content by name '''
        if cfg_name not in self.list_cfg():
            return None

        return file(os.path.join(self._cfg_path, cfg_name)).read()

    def new_cfg(self, cfg_name, content):
        ''' create cfg file with content '''
        cfg_file = os.path.join(self._cfg_path, cfg_name)
        folder = os.path.dirname(cfg_file)
        if not os.path.exists(folder):
            os.makedirs(folder)
        with open(cfg_file, 'w') as file_handle:
            file_handle.writelines(content)

    def list_pxe(self):
        ''' list all pxe files '''
        pxe_files = [
            os.path.split(i)[-1]
            for i in glob.glob(os.path.join(self._pxe_path, '01-*'))
        ]
        return sorted(pxe_files)

    def new_pxe(self, mac, cfg_name):
        ''' create pxe file base on cfg for mac '''
        content = self.get_cfg(cfg_name)
        if not content:
            return None
        content = self.filter_content(content)
        pxe_name = '01-%s' % mac.lower().replace(':', '-')
        pxe_file = os.path.normpath(os.path.join(self._pxe_path, pxe_name))
        with open(pxe_file, 'w') as file_handle:
            file_handle.write(self._pxe_prefix)
            file_handle.writelines(content)

    def get_pxe(self, mac):
        ''' get pxe file content '''
        pxe_name = '01-%s' % mac.lower().replace(':', '-')
        if pxe_name not in self.list_pxe():
            return None

        return file(os.path.join(self._pxe_path, pxe_name)).read()

    def clear_pxe(self, mac):
        ''' remove pxe file '''
        pxe_name = '01-%s' % mac.lower().replace(':', '-')
        pxe_file = os.path.join(self._pxe_path, pxe_name)
        if os.path.exists(pxe_file):
            os.unlink(pxe_file)

    def append_pxe(self, mac, cfg_name):
        ''' append pxe file '''
        content = self.get_cfg(cfg_name)
        if not content:
            return None
        content = self.filter_content(content)
        pxe_name = '01-%s' % mac.lower().replace(':', '-')
        pxe_file = os.path.join(self._pxe_path, pxe_name)
        with open(pxe_file, 'a') as file_handle:
            file_handle.write('\n')
            file_handle.writelines(content)

    def insert_pxe(self, mac, index, cfg_name):
        ''' insert pxe file '''
        content = self.get_cfg(cfg_name)
        if not content:
            return None
        content = self.filter_content(content)
        pxe_name = '01-%s' % mac.lower().replace(':', '-')
        pxe_file = os.path.join(self._pxe_path, pxe_name)
        current_content = self.get_pxe(mac).split('\n')

        indexs = []
        for i, e in enumerate(current_content):
            if e.strip().lower().startswith('label '):
                indexs.append(i)
        total_index = len(indexs) -1
        if index > total_index:
            index = total_index
        if index < 0:
            index = 0
        current_content.insert(indexs[index], content)
        content = '\n'.join(current_content)

        with open(pxe_file, 'w') as file_handle:
            file_handle.writelines(content)

    def filter_content(self, content):
        ''' filter content '''
        return '\n'.join([
            i for i in content.split('\n')
            if ('menu ' not in i) and (i.strip() != '')
        ])


if __name__ == '__main__':
    pxe = Pxe()
    # pxe_cfg.set_cfg_path('test/pxelinux.cfg/os')
    # pxe_cfg.set_pxe_path('test/pxelinux.cfg')
    print pxe.cfg_path()
    print pxe.pxe_path()
    pxe.new_pxe('08:00:27:df:0e:00', 'diskless/centos.cfg')
    pxe.append_pxe('08:00:27:df:0e:00', 'diskless/sles.cfg')
